#!/usr/bin/env python3

import socket
import sys
import tty
import termios
import select
import struct
import fcntl

def get_terminal_size():
    """获取当前终端尺寸"""
    try:
        # TIOCGWINSZ: 获取窗口大小
        ws = fcntl.ioctl(sys.stdout.fileno(), 0x5413, b'\x00'*8)
        rows, cols = struct.unpack("HHHH", ws)[:2]
        return rows, cols
    except:
        return 24, 80  # 默认

def send_window_size(sock, rows, cols):
    """发送 stty 命令设置远程窗口大小"""
    cmd = f"stty cols {cols} rows {rows}\r\n"
    sock.send(cmd.encode())

def main():
    if len(sys.argv) != 3:
        print(f"用法: {sys.argv[0]} <ip> <port>")
        sys.exit(1)

    ip, port = sys.argv[1], int(sys.argv[2])
    sock = socket.socket()
    sock.connect((ip, port))

    # 设置原始模式
    old_settings = termios.tcgetattr(sys.stdin)
    tty.setraw(sys.stdin.fileno())

    try:
        # 发送初始窗口大小
        rows, cols = get_terminal_size()
        send_window_size(sock, rows, cols)

        # 监听窗口变化（SIGWINCH）
        def sigwinch_handler(signum, frame):
            new_rows, new_cols = get_terminal_size()
            send_window_size(sock, new_rows, new_cols)
        signal.signal(signal.SIGWINCH, sigwinch_handler)

        while True:
            rlist, _, _ = select.select([sys.stdin, sock], [], [], 1)
            if sys.stdin in rlist:
                data = sys.stdin.read(1)
                if not data: 
                    break
                sock.send(data.encode())
            if sock in rlist:
                data = sock.recv(4096)
                if not data:
                    break
                sys.stdout.write(data.decode('utf-8', errors='replace'))
                sys.stdout.flush()

    except KeyboardInterrupt:
        pass
    finally:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
        sock.close()

if __name__ == "__main__":
    import signal
    main()
